package api

import (
	"strconv"

	"github.com/gin-gonic/gin"

	"BookStack/internal/application/user"
	"BookStack/internal/interfaces/middleware"
	"BookStack/internal/interfaces/presenter"
)

// UserHandler 用户API处理器
type UserHandler struct {
	userService user.Service
	response    presenter.ResponseFormatter
}

// NewUserHandler 创建用户API处理器
func NewUserHandler(userService user.Service) *UserHandler {
	return &UserHandler{
		userService: userService,
		response:    presenter.NewResponseFormatter(),
	}
}

// RegisterRoutes 注册用户相关路由
func (h *UserHandler) RegisterRoutes(r *gin.RouterGroup) {
	// 公开API
	public := r.Group("")
	{
		public.POST("/register", h.Register)
		public.POST("/login", h.Login)
	}

	// 需要认证的API
	auth := r.Group("/user", middleware.JWTAuth()) // JWT认证中间件
	{
		auth.GET("", h.GetProfile)
		auth.PUT("", h.UpdateProfile)
		auth.PUT("/password", h.ChangePassword)
	}

	// 管理员API
	admin := r.Group("/admin/user", middleware.JWTAuth(), middleware.AdminAuth()) // 管理员权限认证中间件
	{
		admin.GET("/list", h.ListUsers)
		admin.PUT("/:id/role", h.SetRole)
		admin.PUT("/:id/status", h.SetStatus)
		admin.POST("", h.CreateUser)
		admin.DELETE("/:id", h.DeleteUser)
	}
}

// Register 用户注册
func (h *UserHandler) Register(c *gin.Context) {
	var req user.RegisterRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		// 将解析错误直接传递给错误中间件处理
		c.Error(err)
		return
	}

	resp, err := h.userService.Register(c.Request.Context(), req)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Created(c, resp)
}

// Login 用户登录
func (h *UserHandler) Login(c *gin.Context) {
	var req user.LoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		// 将解析错误直接传递给错误中间件处理
		c.Error(err)
		return
	}

	resp, err := h.userService.Login(c.Request.Context(), req)
	if err != nil {
		c.Error(err)
		return
	}

	// 生成JWT令牌
	token, err := middleware.GenerateToken(resp.ID, resp.Username, resp.Role)
	if err != nil {
		c.Error(user.TokenGenerationFailed(err))
		return
	}

	resp.Token = token
	h.response.Success(c, resp)
}

// GetProfile 获取用户信息
func (h *UserHandler) GetProfile(c *gin.Context) {
	userID, _ := middleware.GetUserID(c)

	resp, err := h.userService.GetProfile(c.Request.Context(), userID)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, resp)
}

// UpdateProfile 更新用户信息
func (h *UserHandler) UpdateProfile(c *gin.Context) {
	userID, _ := middleware.GetUserID(c)

	var req user.UpdateProfileRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		// 将解析错误直接传递给错误中间件处理
		c.Error(err)
		return
	}

	if err := h.userService.UpdateProfile(c.Request.Context(), userID, req); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// ChangePassword 修改密码
func (h *UserHandler) ChangePassword(c *gin.Context) {
	userID, _ := middleware.GetUserID(c)

	var req user.ChangePasswordRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		// 将解析错误直接传递给错误中间件处理
		c.Error(err)
		return
	}

	if err := h.userService.ChangePassword(c.Request.Context(), userID, req); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// ListUsers 获取用户列表
func (h *UserHandler) ListUsers(c *gin.Context) {
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))

	// 限制页码和页面大小
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 {
		pageSize = 10
	}

	resp, err := h.userService.GetUsers(c.Request.Context(), page, pageSize)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Paged(c, resp.Items, resp.Total, page, pageSize)
}

// SetRole 设置用户角色
func (h *UserHandler) SetRole(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.Error(user.ValidationFailed(map[string]string{"id": "无效的用户ID"}))
		return
	}

	var req struct {
		Role string `json:"role" binding:"required"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		// 将解析错误直接传递给错误中间件处理
		c.Error(err)
		return
	}

	if err := h.userService.SetRole(c.Request.Context(), uint(id), req.Role); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// SetStatus 设置用户状态
func (h *UserHandler) SetStatus(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.Error(user.ValidationFailed(map[string]string{"id": "无效的用户ID"}))
		return
	}

	// 直接解析请求体，不使用binding标签
	var reqBody map[string]interface{}
	if err := c.ShouldBindJSON(&reqBody); err != nil {
		c.Error(user.ValidationFailed(map[string]string{"body": err.Error()}))
		return
	}

	// 手动提取和验证status字段
	statusVal, exists := reqBody["status"]
	if !exists {
		c.Error(user.ValidationFailed(map[string]string{"status": "status字段是必需的"}))
		return
	}

	// 将interface{}转换为float64（JSON中的数字默认解析为float64）
	statusFloat, ok := statusVal.(float64)
	if !ok {
		c.Error(user.ValidationFailed(map[string]string{"status": "status必须是数字"}))
		return
	}

	// 转换为int并验证值
	status := int(statusFloat)
	if status != 0 && status != 1 {
		c.Error(user.ValidationFailed(map[string]string{"status": "status只能是0或1"}))
		return
	}

	// 调用服务
	if err := h.userService.SetStatus(c.Request.Context(), uint(id), status); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// CreateUser 管理员创建用户
func (h *UserHandler) CreateUser(c *gin.Context) {
	var req user.RegisterRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		// 将解析错误直接传递给错误中间件处理
		c.Error(err)
		return
	}

	resp, err := h.userService.CreateUser(c.Request.Context(), req)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Created(c, resp)
}

// DeleteUser 管理员删除用户
func (h *UserHandler) DeleteUser(c *gin.Context) {
	idStr := c.Param("id")
	id, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		c.Error(user.ValidationFailed(map[string]string{"id": "无效的用户ID"}))
		return
	}

	if err := h.userService.DeleteUser(c.Request.Context(), uint(id)); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}
